home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
PASCAL
/
0921.ZIP
/
GRSEAR.ARC
/
GRSEARCH.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1987-12-25
|
9KB
|
267 lines
program grsearch;
{ Author:
12/26/87 Michael Shunfenthal Compuserve ID [76320,122]
program function: (This routine replaces the procedure InitGraph)
1. find the graphics display type and the driver in any
directory listed in the PATH environment variable.
2. initialize graphics mode with the appropriate driver in that
directory.
}
uses dos,crt,graph;
const
TotalPaths = 20; { max number of directories in the path }
type
bytepatharray = Array [1..TotalPaths, 1..64] of Byte;
maxdirtype = 1..TotalPaths;
var
pc, { when searching: character-in-path counter }
graphstatus, GraphDriver, GraphMode : integer;
listdirstring: string [64];
bgifile : string [8];
procedure graphicsstartup; {define the bgi file to be found}
begin
GraphDriver := Detect; {detect and return current adapter}
DetectGraph(GraphDriver, GraphMode );
case GraphDriver of {set the BGI file to be found}
Reserved,
CGA : bgifile := 'CGA';
MCGA,
EGA, EGA64, EGAMono,
VGA : bgifile := 'EGAVGA';
Hercmono : bgifile := 'HERC';
ATT400 : bgifile := 'ATT';
PC3270 : bgifile := 'PC3270';
end;
graphstatus := GraphResult;
if graphstatus > grOk then { call this function to test result}
begin
writeln('Graphics init error: ', graphstatus);
Halt(1);
end;
end; { graphicsstartup }
procedure searchenvironment ( var dircount : maxdirtype;
var dirlist : bytepatharray );
var
Segment, { the two parts of an address }
offset,
offsetvarstart : Integer; { offset wher the 'P' in PATH... begins }
Procedure Get_PSP; { get the program segment prefix }
var
Regs : Registers;
PSP : Integer;
Begin
Regs.AX := $6200; { Get PSP address }
MsDos (Regs); { Call DOS, int 0x21 }
PSP := Regs.BX; { BX has our PSP }
Segment := MemW[PSP:$2C]; { the offset of $2C indicates the starting
place in memory of our current environment
string }
End; { Get_PSP }
Procedure Read_Env;
{ read the environment area, searching for variables delimited by a null }
procedure locatevariable;
{ search for the specified variable: 'PATH'}
begin
{ parse argument, process search sequentially }
if (Mem[Segment:offset] = ord('P')) and
(Mem[Segment:offset+1] = ord('A')) and
(Mem[Segment:offset+2] = ord('T')) and
(Mem[Segment:offset+3] = ord('H'))
then
offsetvarstart:=offset; { mark where variable begins in memory }
end; { locatevariable }
Begin { Read_Env }
offset := -1; { set initial offsets }
offsetvarstart := -1;
ClrScr;
{ writeln('The DOS environment variables: '); }
While (offset < 32000) do { stop after reading the first 1000
characters of the DOS environment }
begin
offset := offset + 1; { increment the offset by one }
{ call locatevariable to see if it is the first variable
in the environment }
if offset = 0 then locatevariable;
if Mem[Segment:offset] = 0 then
begin
if Mem[Segment:offset+1] = 0 then
begin
{ two nulls in a row indicate the end of the environment. }
{ writeln;
writeln('The DOS environment is ',offset,' bytes long.',
' PATH located at offset: ', offsetvarstart); }
exit
end
else { a single null indicates the end of one variable,
so the call to locatevariable will not find one
as part of another }
begin
offset := offset + 1;
locatevariable;
offset := offset - 1;
{ writeln; }
end
end
else { not a null }
begin
{ write(chr(Mem[Segment:offset]));} { print any value but 0 (null) }
end
End; { end while loop }
End; { Read_Env }
Procedure StorePath;
{ search for each directory delimited by a ';' and store it in an array }
var
Newoff : integer;
Begin { initialize the array to nulls }
for pc := 1 to TotalPaths do FillChar(dirlist,255,0);
pc := 0;
dircount := 1;
{ Found PATH= thus first 5 bytes are PATH= so skip it, then parse by ; }
Newoff := offsetvarstart+5; { see skip message above }
While Newoff< offsetvarstart+1000 do { presuming PATH is smaller than 1000 chars }
begin
if Mem[Segment:NewOff]=0 then
Newoff:=offsetvarstart+1024 { null found, so PATH Search is Complete }
else
if Mem[Segment:Newoff] in [33..41,44..59,61,64..90,92] then
{ are they allowable directory chars? }
if Mem[Segment:Newoff] in [59] then { [59] is the ';', the PATH delim }
begin { end of one subdirectory }
if dircount = TotalPaths then
begin
writeln('Too many Paths encountered... exiting');
Halt(1); { return to DOS with ErrorLevel set to 1 }
end;
pc := 0; dircount := dircount+1; { reset char, increment directory counts }
end
else
begin { save the path character in an array }
pc := pc+1;
dirlist[dircount][pc]:=Mem[Segment:Newoff];
end;
Newoff := Newoff + 1;
end;
end; { StorePath }
Procedure ListPath;
{ display each directory in the path }
var
a, { when displaying: character-in-path counter }
b : integer; { when displaying: number-of-directories counter }
begin
writeln;
writeln('Number of PATH directories: ', dircount, '. Your current path is:');
{ print each directory in the path on a new line }
If dircount > 1
Then
For a:=1 to dircount do { a counts directories in the array }
begin
b:=1; { b counts characters (first index) in the array }
While b < 255 do
if dirlist[a][b] in [32..95] then
begin
{ it is a printable char }
write(chr(dirlist[a][b]));
b:=b+1;
end
else { it is NOT printable... }
b:=256; { something to get out of while loop }
writeln; { a new line }
end { of for loop }
else
writeln('No PATH variable in the environment');
end; { ListPath }
Begin {searchenvironment}
Get_PSP;
Read_Env;
if offsetvarstart > -1 then
begin { if offsetvarstart has not been changed from its initial }
StorePath; { setting to -1, then the variable has not been found }
ListPath;
end
else
writeln ('No path found');
End; {searchenvironment}
procedure bgifind; { search for the given bgifile }
label
1000;
var
listdirbyte : bytepatharray;
maxdirs, countdirs : maxdirtype;
countbyte : integer;
filerecord : searchrec;
begin { bgifind }
searchenvironment (maxdirs, listdirbyte);
{ convert the byte array into an input for findfirst }
if maxdirs > 0 then
for countdirs := 1 to maxdirs do
begin
listdirstring := '';
for countbyte := 1 to 64 do
begin
{ starting with the left end of the byte array, stuff the
character equivalent into the single string variable listdirchar
until the first null is reached. At that byte, substitute a
'\' if the last character wasn't already a '\',
and record the byte number for that array index in enddir }
if listdirbyte[countdirs, countbyte] <> 0 then
listdirstring := listdirstring +
chr (listdirbyte[countdirs, countbyte])
else {null byte: end of directory path }
if copy (listdirstring, length (listdirstring), 1)<>'\' then
begin
listdirstring := listdirstring + '\';
goto 1000;
end;
end;
1000: findfirst ( listdirstring+bgifile+'.bgi', anyfile, filerecord);
if doserror = 0 then
begin
writeln ( 'Found: ', listdirstring+bgifile+'.bgi');
exit;
end
else
writeln ( 'Did not find: ', listdirstring+bgifile+'.bgi',
' Dos error: ', doserror );
end;
end; { bgifind }
begin {main procedure}
graphicsstartup;
bgifind;
writeln ('(press <return>)');readln;
InitGraph (Graphdriver, Graphmode, listdirstring);
graphstatus := GraphResult;
if graphstatus <> grOk then
begin
writeln ('Graphics init error: ', graphstatus);
Halt(1);
end;
outtextxy ( 0, 20, 'I HAVE DONE IT! (press <return>)');
readln;
CloseGraph;
end. {main procedure}